package cpu.footprint.view.photo;

import android.os.Parcelable;
import android.view.View;

/**
 * Base class providing the adapter to populate pages inside of a
 * {@link ViewPager}. You will most likely want to use a more specific
 * implementation of this, such as
 * {@link android.support.v4.app.FragmentPagerAdapter} or
 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
 */
public abstract class PagerAdapter {
	private DataSetObserver mObserver;

	public static final int POSITION_UNCHANGED = -1;
	public static final int POSITION_NONE = -2;

	/**
	 * Used to watch for changes within the adapter.
	 */
	interface DataSetObserver {
		public void onDataSetChanged();
	}

	/**
	 * Return the number of views available.
	 */
	public abstract int getCount();

	/**
	 * Called when a change in the shown pages is going to start being made.
	 * 
	 * @param container
	 *            The containing View which is displaying this adapter's page
	 *            views.
	 */
	public abstract void startUpdate(View container);

	/**
	 * Create the page for the given position. The adapter is responsible for
	 * adding the view to the container given here, although it only must ensure
	 * this is done by the time it returns from {@link #finishUpdate()}.
	 * 
	 * @param container
	 *            The containing View in which the page will be shown.
	 * @param position
	 *            The page position to be instantiated.
	 * @return Returns an Object representing the new page. This does not need
	 *         to be a View, but can be some other container of the page.
	 */
	public abstract Object instantiateItem(View container, int position);

	/**
	 * Remove a page for the given position. The adapter is responsible for
	 * removing the view from its container, although it only must ensure this
	 * is done by the time it returns from {@link #finishUpdate()}.
	 * 
	 * @param container
	 *            The containing View from which the page will be removed.
	 * @param position
	 *            The page position to be removed.
	 * @param object
	 *            The same object that was returned by
	 *            {@link #instantiateItem(View, int)}.
	 */
	public abstract void destroyItem(View container, int position, Object object);

	/**
	 * Called to inform the adapter of which item is currently considered to be
	 * the "primary", that is the one show to the user as the current page.
	 * 
	 * @param container
	 *            The containing View from which the page will be removed.
	 * @param position
	 *            The page position that is now the primary.
	 * @param object
	 *            The same object that was returned by
	 *            {@link #instantiateItem(View, int)}.
	 */
	public void setPrimaryItem(View container, int position, Object object) {
	}

	/**
	 * Called when the a change in the shown pages has been completed. At this
	 * point you must ensure that all of the pages have actually been added or
	 * removed from the container as appropriate.
	 * 
	 * @param container
	 *            The containing View which is displaying this adapter's page
	 *            views.
	 */
	public abstract void finishUpdate(View container);

	public abstract boolean isViewFromObject(View view, Object object);

	public abstract Parcelable saveState();

	public abstract void restoreState(Parcelable state, ClassLoader loader);

	/**
	 * Called when the host view is attempting to determine if an item's
	 * position has changed. Returns {@link #POSITION_UNCHANGED} if the position
	 * of the given item has not changed or {@link #POSITION_NONE} if the item
	 * is no longer present in the adapter.
	 * 
	 * <p>
	 * The default implementation assumes that items will never change position
	 * and always returns {@link #POSITION_UNCHANGED}.
	 * 
	 * @param object
	 *            Object representing an item, previously returned by a call to
	 *            {@link #instantiateItem(View, int)}.
	 * @return object's new position index from [0, {@link #getCount()}),
	 *         {@link #POSITION_UNCHANGED} if the object's position has not
	 *         changed, or {@link #POSITION_NONE} if the item is no longer
	 *         present.
	 */
	public int getItemPosition(Object object) {
		return POSITION_UNCHANGED;
	}

	/**
	 * This method should be called by the application if the data backing this
	 * adapter has changed and associated views should update.
	 */
	public void notifyDataSetChanged() {
		if (mObserver != null) {
			mObserver.onDataSetChanged();
		}
	}

	void setDataSetObserver(DataSetObserver observer) {
		mObserver = observer;
	}
}
